package fm.dongman.modellib

import android.util.Log
import okhttp3.*
import org.json.JSONObject

/**
 * 用于网络的请求
 * Created by shize on 2017/11/14.
 */

class RemoteHelper private constructor() {
    //网络请求对象
    private val mOkHttpClient: OkHttpClient = OkHttpClient()

    /**
     * 解析 Get 请求地址
     * @param parseUrl get请求地址
     * @return 解析失败返回 null，解析成功返回 JSONObject
     */
    fun parseGetUrl(parseUrl: String): JSONObject? {
        var getJson: JSONObject? = null
        try {
            val mRequest = Request.Builder().url(parseUrl).get().build()
            val mResponse = mOkHttpClient.newCall(mRequest).execute()
            getJson = JSONObject(mResponse.body()!!.string())
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return connect(getJson, parseUrl)
    }

    /**
     * 解析 Post 请求地址
     * @param postParse post请求地址
     * @param json 需要传递的json参数
     * @return 解析失败返回 null，解析成功返回 JSONObject
     */
    private fun parsePostUrl(postParse: String, headerMap: Map<String, Any>?, json: String): JSONObject? {
        var postJson: JSONObject? = null
        val mediaType = MediaType.parse("application/json; charset=utf-8")
        val requestBody = RequestBody.create(mediaType, json)
        // 获取头
        val headers = generateHeader(headerMap)
        // 生成 Post 请求
        val request = if (headers == null) {
            Request.Builder().url(postParse).post(requestBody).build()
        } else {
            Request.Builder().url(postParse).headers(headers).post(requestBody).build()
        }
        try {
            val response = mOkHttpClient.newCall(request).execute()
            if (response.isSuccessful) {
                postJson = JSONObject(response.body()!!.string())
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return connect(postJson, postParse + json)
    }

    /**
     * 解析 Post 请求地址
     * @param postParse post请求地址
     * @param bodyMap 键值对
     * @return 解析失败返回 null，解析成功返回 JSONObject
     */
    fun parsePostUrl(postParse: String, bodyMap: Map<String, Any>): JSONObject? =
            parsePostUrl(postParse, null, generatePostUrl(bodyMap))

    /**
     * 解析 Post 请求地址
     * @param postParse post请求地址
     * @param headerMap 头部键值对
     * @param bodyMap body 键值对
     * @return 解析失败返回 null，解析成功返回 JSONObject
     */
    fun parsePostUrl(postParse: String, headerMap: Map<String, Any>, bodyMap: Map<String, Any>): JSONObject? =
            parsePostUrl(postParse, headerMap, generatePostUrl(bodyMap))

    /**
     * 构建 Post 请求
     * @param map 键值对
     * @return Post 请求地址
     */
    private fun generatePostUrl(map: Map<String, Any>): String {
        val jsonObject = JSONObject()
        map.forEach {
            if (it.value != "")
                jsonObject.put(it.key, it.value)
        }
        return jsonObject.toString()
    }

    /**
     * 构建 Post 请求头
     * @param headerMap 请求头参数
     * @return 请求头，没有参数或 headerMap 为 null 时，返回 null
     */
    private fun generateHeader(headerMap: Map<String, Any>?): Headers? {
        if (headerMap == null || headerMap.isEmpty()) return null
        // 创建头
        val headers: Headers.Builder = Headers.Builder()
        headerMap.forEach {
            headers.add(it.key, it.value.toString())
        }
        return headers.build()
    }

    /**
     * 检测连接状态
     * @param jsonObject JSONObject
     * @param hint 测试的类名
     * @return 若测试失败，则打印错误并返回 null ；若测试成功，则返回 JSONObject
     */
    fun connect(jsonObject: JSONObject?, hint: String): JSONObject? {
        if (jsonObject == null) {
            Log.e(javaClass.name, "Json 数据为空！提示：$hint")
            return null
        }
        val code: Int = jsonObject.getInt("code")
        val msg: String = jsonObject.getString("message")
        if (code != 200) {
            Log.e(javaClass.name, "数据获取错误：Code= $code ：信息：$msg ！提示：$hint")
            return null
        }
        Log.d(javaClass.name, "请求数据成功：Code= $code ：信息：$msg ！提示：$hint")
        return jsonObject
    }

    companion object {
        private var INSTANCE: RemoteHelper? = null

        /**
         * 实例对象
         */
        val instance: RemoteHelper
            get() {
                if (INSTANCE == null) {
                    INSTANCE = RemoteHelper()
                }
                return INSTANCE!!
            }
    }
}
